<?php if (!defined('PmWiki')) exit();
/**
 * pmplantuml.php
 * 
 * This file is distributed under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This module allows to add PlantUML diagram inside PmWiki.
 * See the complete documentation for PlantUML syntax here:
 * http://plantuml.sourceforge.net/
 * 
 * Images are generated by the online service http://www.plantuml.com/
 *
 * For example, you can add:
 * 
 * @startuml
 * Bob -> Alice : hello
 * @enduml
 * 
 * Implementation details about PHP integration available here :
 * http://plantuml.sourceforge.net/codephp.html
 *
 * To use this module, simply place this file in the cookbook/ directory and
 * add the following line into config.php:
 *
 *    include_once("$FarmD/cookbook/pmplantuml.php");
 *
 *  2012-11-07 initial release
 *
 */
$RecipeInfo['PmPlantUML']['0.1'] = '2012-11-07';

function doplantuml($str) {
	global $KPV, $KeepToken;

   	$str = preg_replace( "/$KeepToken(\\d+?)$KeepToken/e", '$KPV[$1]', $str);
   	$str = preg_replace( "/&gt;/", ">", $str);
   	$str = preg_replace( "/&lt;/", "<", $str);

	$url = "http://www.plantuml.com/plantuml/img/";
	$url .= encodep($str);
	return Keep('<img src='.$url.' />');
}

Markup('plantuml',
	'fulltext', 
	'/(@start\w+.*?@end\w+)/sexi',
	'doplantuml("$1")');

function encodep($text) {
     $data = utf8_encode($text);
     $compressed = gzdeflate($data, 9);
     return encode64($compressed);
}

function encode6bit($b) {
     if ($b < 10) {
          return chr(48 + $b);
     }
     $b -= 10;
     if ($b < 26) {
          return chr(65 + $b);
     }
     $b -= 26;
     if ($b < 26) {
          return chr(97 + $b);
     }
     $b -= 26;
     if ($b == 0) {
          return '-';
     }
     if ($b == 1) {
          return '_';
     }
     return '?';
}

function append3bytes($b1, $b2, $b3) {
     $c1 = $b1 >> 2;
     $c2 = (($b1 & 0x3) << 4) | ($b2 >> 4);
     $c3 = (($b2 & 0xF) << 2) | ($b3 >> 6);
     $c4 = $b3 & 0x3F;
     $r = "";
     $r .= encode6bit($c1 & 0x3F);
     $r .= encode6bit($c2 & 0x3F);
     $r .= encode6bit($c3 & 0x3F);
     $r .= encode6bit($c4 & 0x3F);
     return $r;
}

function encode64($c) {
     $str = "";
     $len = strlen($c);
     for ($i = 0; $i < $len; $i+=3) {
            if ($i+2==$len) {
                  $str .= append3bytes(ord(substr($c, $i, 1)), ord(substr($c, $i+1, 1)), 0);
            } else if ($i+1==$len) {
                  $str .= append3bytes(ord(substr($c, $i, 1)), 0, 0);
            } else {
                  $str .= append3bytes(ord(substr($c, $i, 1)), ord(substr($c, $i+1, 1)), ord(substr($c, $i+2, 1)));
            }
     }
     return $str;
} 